﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SharpShare.Storage.Security {
    public enum StorageAccessType {
        Neutral = -1,
        Allow,
        Deny
    }

    public sealed class StorageAccessRule {
        public StorageAccessRule(StorageAccessType type, StorageAccessRight right) {
            this.Type = type;
            this.Right = right;
        }

        public static implicit operator StorageAccessRule(StorageAccessRight right) {
            return new StorageAccessRule(StorageAccessType.Neutral, right);
        }
        public static explicit operator StorageAccessRight(StorageAccessRule rule) {
            return rule.Right;
        }

        public static bool operator true(StorageAccessRule rule) {
            if (rule == null) {
                return false;
            }

            return (rule.Type == StorageAccessType.Allow);
        }
        public static bool operator false(StorageAccessRule rule) {
            if (rule == null) {
                return false;
            }

            return (rule.Type == StorageAccessType.Deny);
        }

        public static bool operator ==(StorageAccessRule rule1, StorageAccessRule rule2) {
            if (object.ReferenceEquals(rule1, rule2)) {
                return true;
            }
            if (object.ReferenceEquals(rule1, null) || object.ReferenceEquals(rule2, null)) {
                return false;
            }

            bool equal = (rule1.Right == rule2.Right && rule1.Type == rule2.Type);

            return equal;
        }
        public static bool operator !=(StorageAccessRule rule1, StorageAccessRule rule2) {
            return !(rule1 == rule2);
        }
        public static StorageAccessRule operator +(StorageAccessRule rule) {
            if (rule == null) {
                return null;
            }

            return Allow(rule.Right);
        }
        public static StorageAccessRule operator -(StorageAccessRule rule) {
            if (rule == null) {
                return null;
            }

            return Deny(rule.Right);
        }
        public static StorageAccessRule operator !(StorageAccessRule rule) {
            if (rule == null) {
                return null;
            }

            StorageAccessType newType = rule.Type;

            if (newType == StorageAccessType.Allow) {
                newType = StorageAccessType.Deny;
            } else {
                newType = StorageAccessType.Allow;
            }

            return new StorageAccessRule(newType, rule.Right);
        }

        public StorageAccessType Type { get; private set; }
        public StorageAccessRight Right { get; private set; }

        public override string ToString() {
            return string.Format("{0} {1}", this.Type, this.Right);
        }

        public override bool Equals(object obj) {
            StorageAccessRule other = (obj as StorageAccessRule);

            if (other == null) {
                return false;
            }

            bool equal = (this == other);

            return equal;
        }
        public override int GetHashCode() {
            return ((int)this.Type ^ (int)this.Right);
        }

        public static StorageAccessRule Allow(StorageAccessRight right) {
            return new StorageAccessRule(StorageAccessType.Allow, right);
        }
        public static StorageAccessRule Deny(StorageAccessRight right) {
            return new StorageAccessRule(StorageAccessType.Deny, right);
        }
    }
}
